using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.Vsts.Ranger.Migration.TfsToTfs.Client;
using Microsoft.Vsts.Ranger.Migration.TfsToTfs.Client.Screens;
using Microsoft.Vsts.Ranger.Migration.TfsToTfs;
using System.Xml.Serialization;
using System.IO;

namespace Microsoft.Vsts.Ranger.Migration.TfsToTfs.Client
{
    public partial class EditSession : Form
    {
        private ConfigureVCMapping _vcMappingForm;
        private bool _saved = false;

        private const string c_VCSessionPrefix = "VCSession_";
        private const string c_WITSessionPrefix = "WITSession_";
        private const string c_sessionNumberFormat = "{0:yyyy_MM_dd_HH_mm_ss_fff}";

        public EditSession()
        {
            InitializeComponent();
            chkEnableLinking.Checked = true;
        }


        private void btnAddMapping_Click(object sender, EventArgs e)
        {
            if (EnsureTeamProjectsAreSelected(true))
            {
                _vcMappingForm = new ConfigureVCMapping(teamProjectPickerSource.TeamProjectName, this.teamProjectPickerSource.ServerName, this.teamProjectPickerDest.TeamProjectName, teamProjectPickerDest.ServerName,this.teamProjectPickerSource.UseStoredCredential, this.teamProjectPickerDest.UseStoredCredential);
                _vcMappingForm.MappingComplete += new Microsoft.Vsts.Ranger.Migration.TfsToTfs.Client.Screens.MappingCompletedEventHandler(_vcMappingForm_MappingComplete);

                _vcMappingForm.Show();
            }
        }

        void _vcMappingForm_MappingComplete(object sender, EventArgs e)
        {
            ListViewItem item = lvwMappings.Items.Add( _vcMappingForm.SourcePath );
            item.SubItems.Add(_vcMappingForm.DestinationPath);
            item.SubItems.Add(_vcMappingForm.Cloak.ToString());
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            bool okToSave = false;
            string reason = "";

            if (EnsureTeamProjectsAreSelected(false))
            {
                if (optVersionControl.Checked)
                {
                    if (lvwMappings.Items.Count > 0)
                        okToSave = true;
                    else
                        reason = "Please select at least one folder mapping.";
                }
                else
                {
                    okToSave = true;
                }
            }
            else
            {
                reason = "Please select both a source and a destination Team Project.";
            }

            if (okToSave)
            {
                AddSessionSettingsToConfig();
                _saved = true;
                this.Close();
            }
            else
            {
                MessageBox.Show(reason, "Missing Required Fields", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            }
        }

        private void AddSessionSettingsToConfig()
        {
            Common.SessionFileManager templateFileManager = new Common.SessionFileManager();

            //Load the Template
            templateFileManager.LoadTemplateConfig();

            //Add the server section if this is a new server
            Common.UIApplicationState.SessionFileManager.AddServerSectionIfMissing(teamProjectPickerDest.ServerName, teamProjectPickerDest.ServerUri,teamProjectPickerDest.UseStoredCredential);
            Common.UIApplicationState.SessionFileManager.AddServerSectionIfMissing(teamProjectPickerSource.ServerName, teamProjectPickerSource.ServerUri, teamProjectPickerSource.UseStoredCredential);

            if (optVersionControl.Checked)
            {
                if (Common.UIApplicationState.SessionFileManager.MigrationConfig.VC == null)
                {
                    //Create the VC section if it doesnt yet exist
                    Common.UIApplicationState.SessionFileManager.MigrationConfig.VC = new MigrationConfig.VCElement();
                }

                MigrationConfig.VCSessionElement vcSection = templateFileManager.MigrationConfig.VC.Sessions[0];


                foreach (ListViewItem item in lvwMappings.Items)
                {
                    MigrationConfig.VCSessionMappingElement mappingSection = new MigrationConfig.VCSessionMappingElement();

                    mappingSection.src =  item.SubItems[1].Text;
                    mappingSection.tgt = item.Text;
                    mappingSection.cloak = bool.Parse(item.SubItems[2].Text);

                    vcSection.Mappings.Add(mappingSection);
                }

                string workspaceRootDefaultFolder = System.Configuration.ConfigurationManager.AppSettings["WorkspaceRootDefaultFolder"];


                string sessionNumber = GetUniqueSessionNumber(c_VCSessionPrefix);

                vcSection.id = c_VCSessionPrefix + sessionNumber;
                vcSection.Source.Tfs.server = teamProjectPickerDest.ServerName;

                vcSection.Source.Tfs.Workspace = "TFS2TFSDest_" + sessionNumber;
                vcSection.Source.Tfs.WorkspaceRoot = Path.Combine(workspaceRootDefaultFolder, "Dest" + sessionNumber);

                vcSection.Tfs.server = teamProjectPickerSource.ServerName;
                vcSection.Tfs.Workspace = "TFS2TFSSource_" + sessionNumber;
                vcSection.Tfs.WorkspaceRoot = Path.Combine(workspaceRootDefaultFolder, "Source" + sessionNumber);

                Common.UIApplicationState.SessionFileManager.AddVersionControlSession(vcSection);
            }
            else
            {
                if (Common.UIApplicationState.SessionFileManager.MigrationConfig.WIT == null)
                {
                    //Create the VC section if it doesnt yet exist
                    Common.UIApplicationState.SessionFileManager.MigrationConfig.WIT = new MigrationConfig.WITElement();
                }

                //Load up the template WIT section for default settings
                MigrationConfig.WITSessionElement witSection = templateFileManager.MigrationConfig.WIT.Sessions[0];

                witSection.id = c_WITSessionPrefix + GetUniqueSessionNumber(c_WITSessionPrefix);

                //Leave off the filter if it is blank
                if (txtWorkItemFilterSource.Text.Trim().Length.Equals(0))
                {
                    witSection.Tfs.Filter = null;
                    
                }
                else
                {
                    witSection.Tfs.Filter = txtWorkItemFilterSource.Text;
                }

                if (chkEnableLinking.Checked)
                {
                    witSection.Linking = new MigrationConfig.WitLinkingElement();
                    witSection.Linking.Engine = new MigrationConfig.LinkSessionBaseEngine();

                    if (!string.IsNullOrEmpty(cmbLinkedVCSession.Text))
                    {
                        witSection.Linking.VersionControl = new MigrationConfig.SessionReferenceElement();

                        witSection.Linking.VersionControl.session = cmbLinkedVCSession.Text;
                    }
                    else
                    {
                        witSection.Linking.VersionControl = null;
                    }

                    witSection.Linking.Engine.provider = "TfsLinkProvider";
                }
                else
                {
                    witSection.Linking = null;
                }
                //witSection.Linking.VersionControl.session

                witSection.Tfs.server = teamProjectPickerSource.ServerName;
                witSection.Tfs.Project = teamProjectPickerSource.TeamProjectName;

                //This filter specifies the filter for work items to pull back from the dest to the source team project
                if (txtWorkItemFilterDest.Text.Trim().Length.Equals(0))
                {
                    witSection.Source.Tfs.Filter = null;
                }
                else
                {
                    witSection.Source.Tfs.Filter = txtWorkItemFilterDest.Text;
                }

                witSection.Source.Tfs.server = teamProjectPickerDest.ServerName;
                witSection.Source.Tfs.Project = teamProjectPickerDest.TeamProjectName;

                Common.UIApplicationState.SessionFileManager.AddWorkItemTrackingSection(witSection);
            }

            Common.UIApplicationState.SessionFileManager.SaveFileChanges();
        }

        private string GetUniqueSessionNumber(string sessionNamePrefix)
        {
            string sessionNumber = string.Empty;
            string sessionName = string.Empty;

            //Ensure that session name is unique
            do
            {
                sessionNumber = GetCurrDateTimeString();
                sessionName = sessionNamePrefix + sessionNumber;
            } while (DetermineSessionNameExists(sessionName));

            return sessionNumber;

        }
        private string GetCurrDateTimeString()
        {
            DateTime now = DateTime.Now;
            return string.Format(c_sessionNumberFormat, now);
        }
        private bool DetermineSessionNameExists(string sessionName)
        {
            if (Common.UIApplicationState.SessionFileManager.MigrationConfig.VC != null)
            {
                //Spin thru the VC sessions
                foreach (MigrationConfig.VCSessionElement vcSession in Common.UIApplicationState.SessionFileManager.MigrationConfig.VC.Sessions)
                {
                    if (sessionName.ToUpper().Trim().Equals(vcSession.id.ToUpper().Trim()))
                        return true;
                }
            }

            if (Common.UIApplicationState.SessionFileManager.MigrationConfig.WIT != null)
            {

                //Spin thru the WIT sessions
                foreach (MigrationConfig.WITSessionElement witSession in Common.UIApplicationState.SessionFileManager.MigrationConfig.WIT.Sessions)
                {
                    if (sessionName.ToUpper().Trim().Equals(witSession.id.ToUpper().Trim()))
                        return true;
                }
            }

            return false;

        }


        private void EditSession_Load(object sender, EventArgs e)
        {

            cmbLinkedVCSession.Items.Clear();

            //Load up the VC sessions for linking
            if (Common.UIApplicationState.SessionFileManager.MigrationConfig.VC != null)
            {
                foreach (MigrationConfig.VCSessionElement session in Common.UIApplicationState.SessionFileManager.MigrationConfig.VC.Sessions)
                    cmbLinkedVCSession.Items.Add(session.id);
            }

            //Toggle the VC radio button so that only the VC tab is visible in the initial state
            optVersionControl.Checked = false;
            optVersionControl.Checked = true;

        }

        private void optVersionControl_CheckedChanged_1(object sender, EventArgs e)
        {
            tabSessionDetails.TabPages.Remove(tabWorkItemTracking);

            if (tabSessionDetails.TabPages["tabVersionControl"] == null)
                tabSessionDetails.TabPages.Add(tabVersionControl);

        }

        private void optWorkItems_CheckedChanged(object sender, EventArgs e)
        {
            tabSessionDetails.TabPages.Remove(tabVersionControl);

            if (tabSessionDetails.TabPages["tabWorkItemTracking"] == null)
                tabSessionDetails.TabPages.Add(tabWorkItemTracking);

        }

        private bool EnsureTeamProjectsAreSelected(bool promptUser)
        {
            if (teamProjectPickerDest.ValidSelectionState && teamProjectPickerSource.ValidSelectionState)
            {
                return true;
            }
            else
            {
                if(promptUser)
                    MessageBox.Show("Please Pick a Source and Destination Team Project", "Team Projects Not Selected", MessageBoxButtons.OK, MessageBoxIcon.Warning);
    
                return false;
            }
            
        }

        private void btnRemove_Click(object sender, EventArgs e)
        {
            if (lvwMappings.SelectedItems.Count > 0)
            {
                if(MessageBox.Show("Are you sure that you want to remove this mapping?","Confirm Remove Mapping",MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                    RemoveMapping();
            }
            else
            {
                MessageBox.Show("Please select a mapping be removed.","No Mapping Selected",MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        private void RemoveMapping()
        {
            lvwMappings.SelectedItems[0].Remove();
        }

        private void EditSession_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!_saved && MessageBox.Show("Close without saving changes?", "Confirm Cancel", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
            {
                e.Cancel = true;
            }
        }

        private void chkEnableLinking_CheckedChanged(object sender, EventArgs e)
        {
            if (chkEnableLinking.Checked)
            {
                cmbLinkedVCSession.Enabled = true;
            }
            else
            {
                cmbLinkedVCSession.Enabled = false;
            }
        }

    }
}
